/*
 * semaphores.c
 *
 *  Created on: 28/set/2014
 *      Author: root
 */
#include "semaphores.h"
#include "sharedMemory.h"
#include "mmap.h"


PPMBXSEM mBoxSems;
int mBoxSemsSize;

int binSemAlloc(key_t key, int semflags){
	int retval;
	if((retval = semget(key, 1, semflags))==-1){
		notifyError(ERR_SEM_ALLOC,1,0);
	}
	return retval;
}

int binSemDeAlloc(int semId){
	SEMUN arg;
	int retval;
	if((retval = semctl(semId, 1, IPC_RMID, arg))==-1){
		notifyError(ERR_SEM_DEALLOC,1,0);
	}
	return retval;
}

int binSemInit(int semId){
	SEMUN arg;
	int retval;
	unsigned short values[1];
	values[0]=1;
	arg.array = values;
	if((retval = semctl(semId, 0, SETALL, arg))==-1){
		notifyError(ERR_SEM_INIT,1,0);
	}
	return retval;
}

int binSemWait(int semId){
	int retval;
	struct sembuf operations[1];
	operations[0].sem_num = 0;
	operations[0].sem_op = -1;
	operations[0].sem_flg = SEM_UNDO;
	if((retval = semop(semId, operations, 1))==-1){
		notifyError(ERR_SEM_WAIT,1,0);
	}
	return retval;
}

int binSemPost(int semId){
	int retval;
	struct sembuf operations[1];
	operations[0].sem_num = 0;
	operations[0].sem_op = 1;
	operations[0].sem_flg = SEM_UNDO;
	if((retval = semop(semId, operations, 1))==-1){
		notifyError(ERR_SEM_POST,1,0);
	}
	return retval;
}


void initMBoxSems(char * secretsFile, int secretsFileSize){

	int k, size = 0;
	char ** usrList = NULL;

	if(secretsFile != NULL){
		mBoxSemsSize = getMBoxListSize(secretsFile, secretsFileSize);
		usrList = getUsers(secretsFile, mBoxSemsSize);
		mBoxSems = (PPMBXSEM)getMemory(mBoxSemsSize+1, PPMBXSEM_TYPE);
		memset(mBoxSems,0,mBoxSemsSize+1);

		for(k = 0; k < mBoxSemsSize; k++){
			mBoxSems[k] =(PMBXSEM)getMemory(1, MBXSEM_TYPE);
			memset(mBoxSems[k],0,sizeof(MBXSEM));
			mBoxSems[k]->mBoxSemId = binSemAlloc(IPC_PRIVATE, IPC_CREAT | SEM_UNDO);
			binSemInit(mBoxSems[k]->mBoxSemId);
			size = strlen(usrList[k]);
			mBoxSems[k]->usr = (char *)getMemory(size+1,CHAR_TYPE);
			memset(mBoxSems[k]->usr,'\0',size+1);
			strcat(mBoxSems[k]->usr,usrList[k]);
			free(usrList[k]);
		}
		free(usrList);
	}
}


int getMBoxSem(char *usrname){
	int k, semid = -1;

	for(k = 0; k < mBoxSemsSize; k++){
		if(strcasecmp(mBoxSems[k]->usr, usrname)==0){
			semid = mBoxSems[k]->mBoxSemId;
			break;
		}
	}
	return semid;
}


void freeMBoxSems(){
	int k;

	k=0;
	while(k < mBoxSemsSize){
		free(mBoxSems[k]->usr);
		mBoxSems[k]->usr = NULL;
		binSemDeAlloc(mBoxSems[k]->mBoxSemId);
	}
}

